package com.shchuangzhi.smartguard.core;

import com.elvishew.xlog.XLog;
import com.elvishew.xlog.formatter.message.object.ObjectFormatter;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Created by j_hu on 5/4/17.
 */


public class Job implements Runnable, Notify {
    private int name;
    private boolean suspending;
    private int milliseconds;
    private Date stopUnti;
    private Object data;
    private JobExecutor executor;
    private HashMap<Integer, JobCallback> callbackMap;

    public interface JobExecutor {
        Object Execute();
    }

    public interface JobCallback {
        void Callback(Object result);
    }

    public Job(int name, int milliseconds, JobExecutor executor) {
        this(name, milliseconds, executor, null);
    }

    public Job(int name, int milliseconds, JobExecutor executor, Object data) {
        this.name = name;
        this.milliseconds = milliseconds;
        this.executor = executor;
        this.callbackMap = new HashMap<>();
        this.data = data;
        this.suspending = false;

        Calendar c = Calendar.getInstance();
        c.set(1920, 1, 1);
        this.stopUnti = c.getTime();
    }

    public int getName() {
        return name;
    }

    public Object getData() { return data; }

    public void addCallback(Integer name, JobCallback callback) {
        if (callback != null) {
            callbackMap.put(name, callback);
        }
    }

    public void addNotify(Integer name, Notify notify) {
        NotifyPrinter.getInstance().addNotify(name, notify);
    }

    public void notify(NotifyMessage message) {
        NotifyPrinter.getInstance().notify(message);
    }

    public void start() {
        new Thread(this).start();
    }

    public void suspend() {
        suspending = true;
    }

    public void resume() {
        suspending = false;
    }

    public boolean isRunning() {
        return !suspending;
    }

    @Override
    public void run() {
        try {
            while(stopUnti.getTime() < Clock.now().getTime()){
                if (!suspending) {
                    Object result = executor.Execute();
                    if (callbackMap.size() > 0) {
                        Iterator<Map.Entry<Integer, JobCallback>> iterator = callbackMap.entrySet().iterator();
                        while(iterator.hasNext()) {
                            Map.Entry<Integer, JobCallback> entry = iterator.next();
                            entry.getValue().Callback(result);
                        }
                    }
                }
                Thread.sleep(this.milliseconds);
            }
        } catch (InterruptedException e) {
            XLog.e("", e);
        } catch (Exception e) {
            XLog.e("", e);
        }
    }

    public void restartAt(Date stopUnti) {
        this.stopUnti = stopUnti;
    }

    public static class JobDataHolder {
        private List<Object> list = new ArrayList<>();

        public void addValue(Object value) {
            list.add(value);
        }

        public Object getFirst() {
            Object val = null;
            if (list.size() >= 1) {
                val = list.get(0);
            }
            return val;
        }

        public Object getSecond() {
            Object val = null;
            if (list.size() >= 2) {
                val = list.get(1);
            }
            return val;
        }
    }
}
